package com.gzc.just.play.last.war.sceneserver.battle;

import com.gzc.just.play.last.war.common.handler.BattleSession;
import com.gzc.just.play.last.war.common.handler.BattleSessionManager;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 战斗管理器
 * 负责创建和管理战斗会话，每个战斗会话对应一个虚拟线程
 */
@Component("sceneBattleManager")
public class BattleManager {
    private static final Logger logger = LoggerFactory.getLogger(BattleManager.class);
    
    // 战斗会话管理器
    private BattleSessionManager battleSessionManager;
    
    // 玩家ID到战斗ID的映射
    private final ConcurrentHashMap<Long, Long> playerToBattle = new ConcurrentHashMap<>();
    
    // 战斗ID生成器
    private final AtomicLong battleIdGenerator = new AtomicLong(1000);
    
    @PostConstruct
    public void init() {
        // 获取战斗会话管理器实例并启动
        battleSessionManager = BattleSessionManager.getInstance();
        battleSessionManager.start();
        
        logger.info("BattleManager initialized");
    }
    
    @PreDestroy
    public void destroy() {
        // 停止战斗会话管理器
        if (battleSessionManager != null) {
            battleSessionManager.stop();
        }
        
        logger.info("BattleManager destroyed");
    }
    
    /**
     * 创建新战斗
     * @param battleName 战斗名称
     * @return 战斗ID，创建失败返回-1
     */
    public long createBattle(String battleName) {
        long battleId = battleSessionManager.createBattle(battleName);
        if (battleId > 0) {
            logger.info("Created new battle: {} ({})", battleId, battleName);
        } else {
            logger.error("Failed to create battle: {}", battleName);
        }
        return battleId;
    }
    
    /**
     * 将玩家加入战斗
     * @param playerId 玩家ID
     * @param playerName 玩家名称
     * @param battleId 战斗ID
     * @return 是否成功加入
     */
    public boolean addPlayerToBattle(long playerId, String playerName, long battleId) {
        BattleSession battleSession = battleSessionManager.getBattle(battleId);
        if (battleSession == null) {
            logger.error("Battle {} not found", battleId);
            return false;
        }
        
        // 如果玩家已在其他战斗中，先移除
        Long currentBattleId = playerToBattle.get(playerId);
        if (currentBattleId != null) {
            removePlayerFromBattle(playerId);
        }
        
        // 将玩家加入新战斗
        if (battleSession.addPlayer(playerId, playerName)) {
            playerToBattle.put(playerId, battleId);
            logger.info("Added player {} to battle {}", playerName, battleId);
            return true;
        }
        
        return false;
    }
    
    /**
     * 将玩家从战斗中移除
     * @param playerId 玩家ID
     * @return 是否成功移除
     */
    public boolean removePlayerFromBattle(long playerId) {
        Long battleId = playerToBattle.get(playerId);
        if (battleId == null) {
            logger.warn("Player {} is not in any battle", playerId);
            return false;
        }
        
        BattleSession battleSession = battleSessionManager.getBattle(battleId);
        if (battleSession != null) {
            String playerName = battleSession.getPlayers().stream()
                    .filter(p -> p.getPlayerId() == playerId)
                    .map(BattleSession.BattlePlayer::getPlayerName)
                    .findFirst()
                    .orElse("Unknown");
            
            if (battleSession.removePlayer(playerId)) {
                playerToBattle.remove(playerId);
                logger.info("Removed player {} from battle {}", playerName, battleId);
                
                // 如果战斗中没有玩家了，可以停止战斗
                if (battleSession.getPlayerCount() == 0) {
                    stopBattle(battleId);
                }
                
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * 开始战斗
     * @param battleId 战斗ID
     * @return 是否成功开始
     */
    public boolean startBattle(long battleId) {
        BattleSession battleSession = battleSessionManager.getBattle(battleId);
        if (battleSession == null) {
            logger.error("Battle {} not found", battleId);
            return false;
        }
        
        battleSession.startBattle();
        logger.info("Started battle {}", battleId);
        return true;
    }
    
    /**
     * 暂停战斗
     * @param battleId 战斗ID
     * @return 是否成功暂停
     */
    public boolean pauseBattle(long battleId) {
        BattleSession battleSession = battleSessionManager.getBattle(battleId);
        if (battleSession == null) {
            logger.error("Battle {} not found", battleId);
            return false;
        }
        
        battleSession.pauseBattle();
        logger.info("Paused battle {}", battleId);
        return true;
    }
    
    /**
     * 恢复战斗
     * @param battleId 战斗ID
     * @return 是否成功恢复
     */
    public boolean resumeBattle(long battleId) {
        BattleSession battleSession = battleSessionManager.getBattle(battleId);
        if (battleSession == null) {
            logger.error("Battle {} not found", battleId);
            return false;
        }
        
        battleSession.resumeBattle();
        logger.info("Resumed battle {}", battleId);
        return true;
    }
    
    /**
     * 停止战斗
     * @param battleId 战斗ID
     * @return 是否成功停止
     */
    public boolean stopBattle(long battleId) {
        // 先移除所有玩家
        BattleSession battleSession = battleSessionManager.getBattle(battleId);
        if (battleSession != null) {
            for (BattleSession.BattlePlayer player : battleSession.getPlayers()) {
                playerToBattle.remove(player.getPlayerId());
            }
        }
        
        // 停止战斗会话
        if (battleSessionManager.stopBattle(battleId)) {
            logger.info("Stopped battle {}", battleId);
            return true;
        }
        
        return false;
    }
    
    /**
     * 处理玩家消息
     * @param playerId 玩家ID
     * @param messageId 消息ID
     * @param messageBytes 消息字节数组
     * @return 是否成功处理
     */
    public boolean handlePlayerMessage(long playerId, int messageId, byte[] messageBytes) {
        Long battleId = playerToBattle.get(playerId);
        if (battleId == null) {
            logger.warn("Player {} is not in any battle, ignoring message: {}", playerId, messageId);
            return false;
        }
        
        return battleSessionManager.submitMessage(battleId, playerId, messageId, messageBytes);
    }
    
    /**
     * 处理玩家消息（带Netty上下文）
     * @param playerId 玩家ID
     * @param messageId 消息ID
     * @param messageBytes 消息字节数组
     * @param ctx Netty通道上下文
     * @return 是否成功处理
     */
    public boolean handlePlayerMessage(long playerId, int messageId, byte[] messageBytes, 
                                       ChannelHandlerContext ctx) {
        // 在实际实现中，可能需要将ctx保存起来，以便在战斗处理中使用
        // 例如，用于发送消息回客户端
        return handlePlayerMessage(playerId, messageId, messageBytes);
    }
    
    /**
     * 获取玩家所在的战斗ID
     * @param playerId 玩家ID
     * @return 战斗ID，如果玩家不在任何战斗中返回null
     */
    public Long getPlayerBattleId(long playerId) {
        return playerToBattle.get(playerId);
    }
    
    /**
     * 获取战斗信息
     * @param battleId 战斗ID
     * @return 战斗会话，如果不存在返回null
     */
    public BattleSession getBattleInfo(long battleId) {
        return battleSessionManager.getBattle(battleId);
    }
    
    /**
     * 获取当前活跃的战斗数量
     * @return 活跃战斗数量
     */
    public int getActiveBattleCount() {
        return battleSessionManager.getActiveBattleCount();
    }
    
    /**
     * 获取当前的战斗数量（别名）
     * @return 战斗数量
     */
    public int getBattleCount() {
        return getActiveBattleCount();
    }
    
    /**
     * 获取当前活跃的玩家数量
     * @return 活跃玩家数量
     */
    public int getActivePlayerCount() {
        return playerToBattle.size();
    }
    
    /**
     * 清理已结束的战斗
     */
    public void cleanupFinishedBattles() {
        battleSessionManager.cleanupFinishedBattles();
    }
    
    /**
     * 获取所有战斗列表
     * @return 战斗列表
     */
    public java.util.List<java.util.Map<String, Object>> getBattleList() {
        java.util.List<java.util.Map<String, Object>> battleList = new java.util.ArrayList<>();
        
        // 获取所有活跃的战斗
        java.util.Collection<Long> battleIds = battleSessionManager.getAllActiveBattles();
        for (Long battleId : battleIds) {
            BattleSession battleSession = battleSessionManager.getBattle(battleId);
            if (battleSession != null) {
                java.util.Map<String, Object> battleInfo = new java.util.HashMap<>();
                battleInfo.put("battleId", battleId);
                battleInfo.put("name", battleSession.getBattleName());
                battleInfo.put("status", battleSession.getBattleState().name());
                battleInfo.put("playerCount", battleSession.getPlayerCount());
                battleInfo.put("maxPlayers", battleSession.getMaxPlayers());
                battleInfo.put("createTime", battleSession.getCreateTime());
                battleList.add(battleInfo);
            }
        }
        
        return battleList;
    }
    
    /**
     * 获取玩家状态
     * @param playerId 玩家ID
     * @return 玩家状态，如果玩家不在任何战斗中返回null
     */
    public java.util.Map<String, Object> getPlayerStatus(Long playerId) {
        java.util.Map<String, Object> playerStatus = null;
        
        Long battleId = playerToBattle.get(playerId);
        if (battleId != null) {
            BattleSession battleSession = battleSessionManager.getBattle(battleId);
            if (battleSession != null) {
                playerStatus = new java.util.HashMap<>();
                playerStatus.put("playerId", playerId);
                playerStatus.put("inBattle", true);
                playerStatus.put("battleId", battleId);
                playerStatus.put("battleName", battleSession.getBattleName());
                playerStatus.put("battleStatus", battleSession.getBattleState().name());
                
                // 获取玩家在战斗中的详细信息
                BattleSession.BattlePlayer player = battleSession.getPlayers().stream()
                    .filter(p -> p.getPlayerId() == playerId)
                    .findFirst()
                    .orElse(null);
                
                if (player != null) {
                    playerStatus.put("playerName", player.getPlayerName());
                    playerStatus.put("joinTime", player.getJoinTime());
                    playerStatus.put("isReady", player.isReady());
                } else {
                    playerStatus.put("playerName", "Unknown");
                }
            }
        }
        
        return playerStatus;
    }
}